package com.tfleo.mealssenger;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.tfleo.mealssenger.R;
import com.tfleo.mealssenger.adapter.MenuGalleryAdapter;
import com.tfleo.mealssenger.balloon.CustomOverlayItem;
import com.tfleo.mealssenger.balloon.PlacesOverlay;
import com.tfleo.mealssenger.object.Food;
import com.tfleo.mealssenger.object.Place;
import com.tfleo.mealssenger.service.ChatService;
import com.tfleo.mealssenger.utility.DataFetcher;
import com.tfleo.mealssenger.utility.PlaceIconFetcher;
import com.tfleo.mealssenger.utility.SecurityTools;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;

public class ChatActivity extends MapActivity {
	private static final String MARK_FLAG = "##";

	private Context mContext;

	private MapView vMap;
	private MapController mMapController;

	private List<Overlay> mMapOverlays;
	private ChatOverlay mPlacesOverlay;
	private ChatOverlay mMarkedOverlay;

	private LocationManager mLocationManager;
	private LocationListener mLocationListener;

	private SharedPreferences mSharedPref;
	private SharedPreferences.Editor mPrefEditor;

	private String mProvider = LocationManager.GPS_PROVIDER;
	//protected Location currentBestLocation;

	private double mFocusLatitude, mFocusLongitude;
	private GeoPoint mFocusPos;
	private MapOverlay mFocusOverlay;


	private ImageView mCurrentMarker;
	private ImageView mFriendMarker;
	private LayoutInflater mInflater;
	private Vector<Conversation> mData;
	protected Conversation rowData;

	private ArrayList<Place> mPlaces;
	private ArrayList<Food> mFoods;
	private GeoPoint mPos;
	private Location mCurrentBestLocation;

	private ListView listView;
	private EditText vTextBox;
	private TextView vPeerName;
	private ViewSwitcher vSwitcher;
	private TextView vPlaceName;
	private TextView vPlaceAddress;
	private TextView vPlaceCategory;
	private Button vBackBtn;
	private Button vMarkBtn;
	private Gallery vFoodGallery;

	private Button vSendBtn;
	private boolean inMapView = true;

	private static final String JID = "@ip-10-130-59-102";
	private CustomAdapter adapter;
	private MenuGalleryAdapter mFoodAdapter;

	private int peerId;
	private String peerName;
	private String peerChatName;
	private int mCurrentPlace;
	double myLatitude, myLongitude, peerLatitude, peerLongitude;
	
	private int mMyId;
	private String mAuth;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.chat_layout);
		mContext = this;
		
		mPlaces = new ArrayList<Place>();
		
		mSharedPref = getSharedPreferences(Main.USER_DATA, MODE_PRIVATE);
		mPrefEditor = mSharedPref.edit();
		
		mMyId = mSharedPref.getInt(Main.USER_ID, 0);
		mAuth = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID); //for authentication

		mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
		mData = new Vector<Conversation>();

		vSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
		vPlaceName = (TextView) findViewById(R.id.place_name);
		vPlaceAddress = (TextView) findViewById(R.id.place_addr);
		vPlaceCategory = (TextView) findViewById(R.id.place_catg);
		vPeerName = (TextView) findViewById(R.id.name);

		vBackBtn = (Button) findViewById(R.id.back_btn);
		vBackBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				vSwitcher.showPrevious();
				inMapView = true;
			}
		});

		vMarkBtn = (Button) findViewById(R.id.mark_btn);
		vMarkBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				String to = peerChatName + JID;//"admin@ip-10-130-59-102";
				String text = MARK_FLAG + mCurrentPlace;

				Intent intent = new Intent(ChatService.MEALSSENGER_CHATSEND);

				intent.putExtra("message", text);
				intent.putExtra("toUser", to);
				sendBroadcast(intent);
			}
		});

		adapter = new CustomAdapter(this, mData);
		listView = (ListView) findViewById(R.id.chat_list);
		listView.setAdapter(adapter);

		vFoodGallery = (Gallery) findViewById(R.id.food_gallery);

		vSendBtn = (Button) findViewById(R.id.send_btn);
		vSendBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				String to = peerChatName + JID;//"admin@ip-10-130-59-102";
				String text = vTextBox.getText().toString();

				Intent intent = new Intent(ChatService.MEALSSENGER_CHATSEND);

				intent.putExtra("message", text);
				intent.putExtra("toUser", to);
				sendBroadcast(intent);

				mData.add(new Conversation(0, text));
				//setListAdapter();
				adapter = new CustomAdapter(mContext, mData);
				listView.setAdapter(adapter);
				listView.setSelection(adapter.getCount()-1);

				vTextBox.setText("");
			}
		});

		Bundle extras = getIntent().getExtras();
		if(extras != null) {
			peerId = extras.getInt("id");
			peerChatName = Integer.toString(peerId);
			peerName = extras.getString("name");
			vPeerName.setText(peerName);

			SharedPreferences chatPref = getSharedPreferences(ChatService.TAG, MODE_PRIVATE);
			SharedPreferences.Editor chatEditor = chatPref.edit();
			Log.i("aaa", "putting in pref: " + peerId); //TODO: cant use shared pref
			chatEditor.putInt(ChatService.CHAT_WITH, peerId);
			chatEditor.commit();

			Intent intent = new Intent(ChatService.MEALSSENGER_CHATSEND);

			intent.putExtra("toUser", peerChatName);
			sendBroadcast(intent);


		} else {
			Toast.makeText(mContext, "Error: Bundle is null!", Toast.LENGTH_SHORT);
			finish();
		}
		
		UpdateLocationTask updateTask = new UpdateLocationTask();
		updateTask.execute();

		ChatService.actionStart(getApplicationContext());
		mPrefEditor.putBoolean(Main.ONLINE, true);
		mPrefEditor.commit();

		//get location from GPS or NETWORK
		mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 

		if(!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			mProvider = LocationManager.NETWORK_PROVIDER;
			//Toast.makeText(getApplicationContext(), "Switching provider", Toast.LENGTH_SHORT).show();
		}

		mLocationListener = new MyLocationListener();

		vMap = (MapView) findViewById(R.id.chat_map);
		vMap.setBuiltInZoomControls(true);
		mMapController = vMap.getController();

		mMapOverlays = vMap.getOverlays();
		mPlacesOverlay = new ChatOverlay(this.getResources().getDrawable(R.drawable.place_marker), vMap);
		mMarkedOverlay = new ChatOverlay(this.getResources().getDrawable(R.drawable.place_marker2), vMap);
		mCurrentBestLocation = mLocationManager.getLastKnownLocation(mProvider);
		FetchFriendLocationTask loctask = new FetchFriendLocationTask();
		loctask.execute(peerId);

		//mLocationManager.requestSingleUpdate(mProvider, mLocationListener, null);

		vTextBox = (EditText) findViewById(R.id.textbox);

		String message = extras.getString("message");
		if(message != null && extras.getBoolean("from_notif")) {
			if(message.startsWith("##")) {
				int id = 0;
				try {
					id = Integer.parseInt(message.substring(2));
					if(!inMapView) {
						vSwitcher.showPrevious();
					}
					FetchPlaceTask task = new FetchPlaceTask();
					task.execute(id, 1);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}

			} else {
				// Add the incoming message to the list view

				String[] messageCollection;
				messageCollection = message.split("\\|");

				for(int i = messageCollection.length - 1; i >= 0; i--) {
					mData.add(new Conversation(1, messageCollection[i]));
				}
				//mData.add(new Conversation(1, message));
				/*mHandler.post(new Runnable() {
					public void run() {*/
				adapter = new CustomAdapter(mContext, mData);
				listView = (ListView) findViewById(R.id.chat_list);
				listView.setAdapter(adapter);
				listView.setSelection(adapter.getCount()-1);
			}
		}

		//registerReceiver(mStatusReceiver, new IntentFilter(ChatService.MEALSSENGER_CHAT_STATUS));
		//ChatService.actionGetStatus(getApplicationContext(), Integer.toString(peerId));

		registerReceiver(mMessageReceiver,
				new IntentFilter(ChatService.MEALSSENGER_CHATRECEIVE));
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK)) {
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onDestroy() {
		try {
			unregisterReceiver(mMessageReceiver);
			unregisterReceiver(mStatusReceiver);
		} catch(IllegalArgumentException e) {
			e.printStackTrace();
		}
		super.onDestroy();
	}

	@Override
	public void onPause() {
		super.onPause();
	}

	@Override
	public void onStop() {
		super.onStop();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * Update the map marker to show current location
	 * 
	 * @param location The new location to be shown
	 */
	protected void updateLocation(Location location) {
		mPos = new GeoPoint(
				(int) (location.getLatitude() * 1E6),
				(int) (location.getLongitude() * 1E6));

		GeoPoint peerPos = new GeoPoint(
				(int) (peerLatitude * 1E6),
				(int) (peerLongitude * 1E6));

		MapView.LayoutParams lp = new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT,
				mPos,
				MapView.LayoutParams.CENTER);

		MapView.LayoutParams lp2 = new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT,
				peerPos,
				MapView.LayoutParams.CENTER);


		//set new marker if it is not yet set
		if(mCurrentMarker != null) {
			mCurrentMarker.setLayoutParams(lp);
		} else {
			mCurrentMarker = new ImageView(this);
			mCurrentMarker.setImageResource(R.drawable.my_marker);
			vMap.addView(mCurrentMarker, lp);
		}

		if(mFriendMarker != null) {
			mFriendMarker.setLayoutParams(lp2);
		} else {
			mFriendMarker = new ImageView(this);
			mFriendMarker.setImageResource(R.drawable.friend_marker);
			vMap.addView(mFriendMarker, lp2);
		}

		//clear container
		//mMapOverlays.clear();
		//mPlacesOverlay.clear();

		//get middle point
		myLatitude = location.getLatitude();
		myLongitude = location.getLongitude();

		double deltaLong = Math.toRadians(peerLongitude - myLongitude);

		//Convert input values to radians  
		myLatitude = Math.toRadians(myLatitude);  
		myLongitude = Math.toRadians(myLongitude);  
		peerLatitude = Math.toRadians(peerLatitude);  
		peerLongitude = Math.toRadians(peerLongitude);    

		double Bx = Math.cos(peerLatitude) * Math.cos(deltaLong);  
		double By = Math.cos(peerLatitude) * Math.sin(deltaLong);  
		mFocusLatitude = Math.toDegrees(Math.atan2(Math.sin(myLatitude) + Math.sin(peerLatitude),  
				Math.sqrt((Math.cos(myLatitude) + Bx) * (Math.cos(myLatitude) + Bx) + By * By)));  
		mFocusLongitude = Math.toDegrees(myLongitude + Math.atan2(By, Math.cos(myLatitude) + Bx));

		mFocusPos = new GeoPoint(
				(int) (mFocusLatitude * 1E6),
				(int) (mFocusLongitude * 1E6));


		//add nearby Location

		mMapController.zoomToSpan(Math.abs(mPos.getLatitudeE6() - peerPos.getLatitudeE6()), 
				Math.abs(mPos.getLongitudeE6() - peerPos.getLongitudeE6()));
		//mMapController.animateTo(mFocusPos);
		//mMapController.setZoom(17);
		//vMap.invalidate();
		mCurrentBestLocation = location;
		FetchNearbyTask task = new FetchNearbyTask();
		task.execute(mFocusLongitude, mFocusLatitude);
	}

	private class FetchNearbyTask extends AsyncTask<Double, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Double... point) {
			mPlaces = DataFetcher.fetchNearby(point[0], point[1], 0, false, "");
			if(mPlaces == null) {
				return false;
			}
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(result) {
				mMapOverlays.clear();
				mPlacesOverlay.clear();

				mFocusOverlay = new MapOverlay();
				mMapOverlays.add(mFocusOverlay);
				for(int i = 0; i < mPlaces.size(); i++) {
					Place p = mPlaces.get(i);

					float latitude = p.latitude;
					float longitude = p.longitude;

					Location target = new Location(LocationManager.NETWORK_PROVIDER);
					target.setLatitude(latitude);
					target.setLongitude(longitude);

					p.setDistance((int)(mCurrentBestLocation.distanceTo(target)));

					GeoPoint otherPos = new GeoPoint(
							(int) (latitude * 1E6),
							(int) (longitude * 1E6));
					CustomOverlayItem thisOverlay = new CustomOverlayItem(otherPos, i,
							p.name, p.description, p.category, false);
					Log.i("aaa", "add size:" + mPlaces.size() +  " pos:" + i);
					mPlacesOverlay.addOverlay(thisOverlay);
					mMapOverlays.add(mPlacesOverlay);
				}

				mMapController.animateTo(mFocusPos);
				vMap.invalidate();
			} else {
				Toast.makeText(mContext, "Error: Connection with server failed!", Toast.LENGTH_SHORT).show();
			}
		}
	}

	private class FetchFoodTask extends AsyncTask<Integer, Void, Boolean> {
		private ProgressDialog mProgressDialog;

		@Override    
		protected void onPreExecute() {       
			super.onPreExecute();
			mProgressDialog = new ProgressDialog(mContext);
			mProgressDialog.setMessage("Loading...");
			mProgressDialog.setCancelable(false);
			mProgressDialog.setIndeterminate(true);
			mProgressDialog.show();
		}

		@Override
		protected Boolean doInBackground(Integer... id) {
			int placeId = id[0];

			mFoods = DataFetcher.fetchMenu(placeId);
			if(mFoods == null) {
				return false;
			}
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(result) {
				mFoodAdapter = new MenuGalleryAdapter(mContext, mFoods, mInflater);
				vFoodGallery.setAdapter(mFoodAdapter);
				vFoodGallery.setCallbackDuringFling(false);
				mProgressDialog.dismiss();
			} else {
				Toast.makeText(mContext, "Error: Connection with server failed!", Toast.LENGTH_SHORT).show();
				mProgressDialog.dismiss();
			}
		}
	}

	private class FetchPlaceTask extends AsyncTask<Integer, Void, Place> {	
		@Override
		protected Place doInBackground(Integer... id) {
			int placeId = id[0];
			if(id[1] == 1) {
				updateLocation(mCurrentBestLocation);
			}

			return DataFetcher.fetchPlace(placeId);

		}

		@Override
		protected void onPostExecute(Place p) {
			if(p != null) {
				mMapOverlays.clear();
				mMarkedOverlay.clear();
				mMapOverlays.add(mFocusOverlay);
				mMapOverlays.add(mPlacesOverlay);
				
				float latitude = p.latitude;
				float longitude = p.longitude;

				Location target = new Location(LocationManager.NETWORK_PROVIDER);
				target.setLatitude(latitude);
				target.setLongitude(longitude);
				
				p.setDistance((int)(mCurrentBestLocation.distanceTo(target)));

				GeoPoint otherPos = new GeoPoint(
						(int) (latitude * 1E6),
						(int) (longitude * 1E6));
				CustomOverlayItem thisOverlay = new CustomOverlayItem(otherPos, mPlaces.size(),
						p.name, p.description, p.category, false);
				mPlaces.add(p);
				mMarkedOverlay.addOverlay(thisOverlay);
				mMapOverlays.add(mMarkedOverlay);
				mMapController.animateTo(otherPos);
				vMap.invalidate();
			} else {
				Toast.makeText(mContext, "Error: Connection with server failed!", Toast.LENGTH_SHORT).show();
			}
		}
	}

	private class FetchFriendLocationTask extends AsyncTask<Integer, Void, Boolean> {	
		@Override
		protected Boolean doInBackground(Integer... id) {
			return getUserLocation(id[0]);	
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(result) {

			} else {
				peerLongitude = myLongitude;
				peerLatitude = myLatitude;
			}

			mLocationManager.requestSingleUpdate(mProvider, mLocationListener, null);
		}
	}

	private boolean getUserLocation(int userId) {
		if(userId == 0) return false;
		try {
			URL url = new URL(Main.SERVER_URL + "user/" + userId + "/location&me=" + mMyId + "&auth=" + mAuth);
			URLConnection conn = url.openConnection();
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

			String line;
			if((line = in.readLine()) != null) {
				JSONObject jo = new JSONObject(line);

				if(jo.getInt("code") == 1) {
					JSONObject jloc = jo.getJSONObject("response");
					peerLongitude = Float.parseFloat(jloc.getString("lon"));
					peerLatitude = Float.parseFloat(jloc.getString("lat"));
					return true;
				}
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return false;
	}

	/**
	 * Listener class to handle changes in location and provider
	 */
	public class MyLocationListener implements LocationListener {
		public void onLocationChanged(Location location) {
			if(location != null) {
				mCurrentBestLocation = location;
				updateLocation(location);
			}
		}

		public void onProviderDisabled(String provider) {
			mProvider = (provider == LocationManager.GPS_PROVIDER) ? 
					LocationManager.NETWORK_PROVIDER : LocationManager.GPS_PROVIDER;
			Toast.makeText(getApplicationContext(), "Switching provider", Toast.LENGTH_SHORT).show();
		}

		public void onProviderEnabled(String provider) {
			mProvider = (provider == LocationManager.GPS_PROVIDER) ? 
					LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER;
			Toast.makeText(getApplicationContext(), "Switching provider", Toast.LENGTH_SHORT).show();
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
			if(status != LocationProvider.AVAILABLE) {
				mProvider = (provider == LocationManager.GPS_PROVIDER) ? 
						LocationManager.NETWORK_PROVIDER : LocationManager.GPS_PROVIDER;
			}
			Toast.makeText(getApplicationContext(), "Switching provider", Toast.LENGTH_SHORT).show();
		}
	}

	private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			Log.i("aaa", "get message");
			String message = intent.getStringExtra("message");

			if(message.startsWith("##")) {
				int id = 0;
				try {
					id = Integer.parseInt(message.substring(2));
					if(!inMapView) {
						vSwitcher.showPrevious();
					}
					FetchPlaceTask task = new FetchPlaceTask();
					task.execute(id, 0);
					
					mData.add(new Conversation(1, "**Your friend has just marked a place!**"));

					adapter = new CustomAdapter(mContext, mData);
					
					listView.setAdapter(adapter);
					listView.setSelection(adapter.getCount()-1);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}

				return;
			}
			// Add the incoming message to the list view
			mData.add(new Conversation(1, message));

			adapter = new CustomAdapter(mContext, mData);
			
			listView.setAdapter(adapter);
			listView.setSelection(adapter.getCount()-1);
		}
	};

	private BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			/*Boolean status = intent.getBooleanExtra("status", false);
			String location = intent.getStringExtra("location");
			if(location == null) {
				Log.e("aaa", "location null");
				location = "";
			}
			String[] coordinate;
			coordinate = location.split(" ");
			if(coordinate.length <= 0) {
				return;
			}
			try {
				peerLongitude = Double.parseDouble(coordinate[0]);
				peerLatitude = Double.parseDouble(coordinate[1]);
			} catch(Exception e) {
				e.printStackTrace();
				peerLongitude = myLongitude;
				peerLatitude = myLatitude;
			}

			if(status) {
			} else {
			}*/
		}
	};

	/**
	 * Extension of Overlay class to handle tap on map and draw a marker
	 * on the tap location
	 */
	class MapOverlay extends com.google.android.maps.Overlay {
		boolean isPinch;
		@Override
		public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
			super.draw(canvas, mapView, shadow);                   

			//Translate the GeoPoint to screen pixels
			Point screenPts = new Point();
			mapView.getProjection().toPixels(mFocusPos, screenPts);

			//Add marker
			Bitmap bmp = BitmapFactory.decodeResource(
					getResources(), R.drawable.star_marker);            
			canvas.drawBitmap(bmp, screenPts.x, screenPts.y, null);         
			return false;
		}

		@Override
		public boolean onTap(GeoPoint p, MapView mapView) {   
			if (isPinch){
				return false;
			} else{
				mFocusPos = p;
				//Toast.makeText(getBaseContext(), mMyPos.getLatitudeE6()/1E6 + "," + 
				//				mMyPos.getLongitudeE6()/1E6 , Toast.LENGTH_SHORT).show();
				mFocusLatitude = mFocusPos.getLatitudeE6()/1E6;
				mFocusLongitude = mFocusPos.getLongitudeE6()/1E6;

				FetchNearbyTask task = new FetchNearbyTask();
				task.execute(mFocusLongitude, mFocusLatitude);

				return true;
			}
		}

		@Override
		public boolean onTouchEvent(MotionEvent e, MapView mapView) {
			int fingers = e.getPointerCount();
			if(e.getAction() == MotionEvent.ACTION_DOWN ){
				isPinch = false;  // Touch DOWN, don't know if it's a pinch yet
			}
			if(e.getAction() == MotionEvent.ACTION_MOVE && fingers==2 ){
				isPinch = true;   // Two fingers, def a pinch
			}
			return super.onTouchEvent(e,mapView);
		}

	}

	private class Conversation {
		protected int mId;
		protected String userComment;

		Conversation(int id, String comment) {
			mId = id;
			userComment = comment;
		}

		@Override
		public String toString() {
			return mId + " " + userComment;
		}
	}

	private class CustomAdapter extends ArrayAdapter<Conversation> {
		public CustomAdapter(Context context, List<Conversation> objects) {
			super(context, 0, objects);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {   
			ViewHolder holder = null;
			//TextView userView = null;
			TextView commentView = null;
			//ImageView image = null;
			Conversation rowData = getItem(position);

			if(convertView == null || rowData.mId != convertView.getId()) {
				if(rowData.mId == 0) {
					convertView = mInflater.inflate(R.layout.chat_me_entry, null);
				} else {
					convertView = mInflater.inflate(R.layout.chat_friend_entry, null);
				}
				holder = new ViewHolder(convertView);
				convertView.setId(rowData.mId);
				convertView.setTag(holder);
			}

			holder = (ViewHolder) convertView.getTag();

			if(rowData.mId == 0) {
				commentView = holder.getComment();
				commentView.setText(rowData.userComment);
			} else {
				commentView = holder.getFriendComment();
				commentView.setText(rowData.userComment);
			}

			//image = holder.getImage();
			//image.setImageResource(imgid[rowData.mId]);

			return convertView;
		}
	}

	/**
	 * Holder for each view to be shown in each row
	 */
	private class ViewHolder {
		private View mRow;
		private TextView mCommentView = null;
		private TextView mFriendCommentView = null;
		//private ImageView mImageView = null; 

		public ViewHolder(View row) {
			mRow = row;
		}


		public TextView getComment() {
			if(mCommentView == null) {
				mCommentView = (TextView) mRow.findViewById(R.id.comment);
			}
			return mCommentView;
		}

		public TextView getFriendComment() {
			if(mFriendCommentView == null) {
				mFriendCommentView = (TextView) mRow.findViewById(R.id.comment);
			}
			return mFriendCommentView;
		}

		//public ImageView getImage() {
		//	if(mImageView == null){
		//		mImageView = (ImageView) mRow.findViewById(R.id.stall_food_img);
		//	}
		//	return mImageView;
		//}
	}

	public class ChatOverlay extends PlacesOverlay {

		public ChatOverlay(Drawable defaultMarker, MapView mapView) {
			super(boundCenterBottom(defaultMarker), mapView);
		}

		@Override
		protected boolean onBalloonTap(int index, CustomOverlayItem item) {
			vSwitcher.showNext();
			//Log.i("aaa", "" + index);
			inMapView = false;
			int pos = item.getId();
			//Log.i("ChatActivity", "size:" + mPlaces.size() +  " pos:" + pos);
			Place p = mPlaces.get(pos);
			vPlaceName.setText(p.name);
			vPlaceAddress.setText(p.address);
			vPlaceCategory.setText(p.category);
			vPlaceCategory.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(
					PlaceIconFetcher.getIcon(p.category)), null, null, null);
			mCurrentPlace = p.id;

			FetchFoodTask task = new FetchFoodTask();
			task.execute(p.id);


			return true;
		}
	}
	
	private boolean updateLocationToServer() {
		HttpClient httpclient = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(Main.SERVER_URL + "user/updatelocation");

		float lat, lon;
		SharedPreferences sharedPref = getSharedPreferences(Main.USER_DATA, MODE_PRIVATE);
		SharedPreferences.Editor prefEditor = sharedPref.edit();

		LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
		String provider = LocationManager.GPS_PROVIDER;
		if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			provider = LocationManager.NETWORK_PROVIDER;
			//Toast.makeText(getApplicationContext(), "Switching provider", Toast.LENGTH_SHORT).show();
		}
		Location location = locationManager.getLastKnownLocation(provider);
		if(location == null) {
			lat = sharedPref.getFloat(Main.LAST_LATITUDE, 0);
			lon = sharedPref.getFloat(Main.LAST_LONGITUDE, 0);
		} else {
			lat = (float) location.getLatitude();
			lon = (float) location.getLongitude();

			prefEditor.putFloat(Main.LAST_LATITUDE, lat);
			prefEditor.putFloat(Main.LAST_LONGITUDE, lon);
			prefEditor.commit();
		}
		
		//Log.i("aaa", Float.toString(lat) + " " + Float.toString(lon));
		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
			nameValuePairs.add(new BasicNameValuePair("id", Integer.toString(sharedPref.getInt(Main.USER_ID, 0))));
			nameValuePairs.add(new BasicNameValuePair("email", sharedPref.getString(Main.EMAIL, "")));
			nameValuePairs.add(new BasicNameValuePair("password", SecurityTools.decrypt(SecurityTools.MASTER_KEY, 
					sharedPref.getString(Main.TOKEN, ""))));
			nameValuePairs.add(new BasicNameValuePair("last_lat", Float.toString(lat)));
			nameValuePairs.add(new BasicNameValuePair("last_lon", Float.toString(lon)));
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			
			// Execute HTTP Post Request
			ResponseHandler<String> responseHandler = new BasicResponseHandler();
			String responseBody = httpclient.execute(httppost, responseHandler);
			//Log.i("aaa", responseBody);
			JSONObject response = new JSONObject(responseBody);
			if(response.getInt("code") == 1) {
				return true;
			} else {
				return false;
			}
		} catch(Exception e){
			e.printStackTrace();
		}
		
		return false;

	}
	
	private class UpdateLocationTask extends AsyncTask<Void , Void, Boolean> {
		@Override
		protected Boolean doInBackground(Void... v) {
			if(peerName == null)
				peerName = getName(peerId);
			return updateLocationToServer();
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(result) {
				Log.i("aaa", "updated");
			} else {
				Log.e("aaa", "error can't update");
			}
			
			vPeerName.setText(peerName);
		}

	}
	
	private String getName(int id) {
		try {
			URL url = new URL(Main.SERVER_URL + "get_name.php?user_id=" + id);
			URLConnection conn = url.openConnection();
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

			String body;
			if((body = in.readLine()) != null) {
				JSONObject jo = new JSONObject(body);
				if(jo.getInt("code") == 1) {
					JSONObject response = jo.getJSONObject("response");
					
					return response.getString("name");
				} else {
					return "";
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return "";
	}

}
